<?php
declare (strict_types = 1);

namespace app\frontend\controller;

use app\frontend\model\TaskContent;
use app\frontend\model\TimeSlice;
use think\facade\Db;
use think\facade\Filesystem;
use think\facade\Validate;

class SubTask extends Base
{
    // 子任务页面
    public function index()
    {
        $pid = (int)input('get.pid', '', 'strip_tags');

        return view('', ['pid' => $pid]);
    }

    // 任务列表数据接口
    public function list()
    {
        $pid = request()->param('pid');
        $page = request()->param('page');
        $limit = request()->param('limit');
        $status = request()->param('status');
        $name = request()->param('name');

        if ($status == 'all') {
            $status = [1, 2, 3, 4, 5];
        } else {
            $status = [$status];
        }
        $taskList = \app\frontend\model\Task::field('id,name,start_time,end_time,status,priority')
            ->where([
                ['pid', '=', $pid],
                ['name', 'like', '%'.$name.'%'],
                ['status', 'in', $status]
            ])->order('id', 'desc')
            ->paginate([
                'list_rows' => $limit,
                'var_page' => 'page',
                'page' => $page,
                'query' => [
                    'name' => $name,
                    'status' => $status
                ]
            ]);

        $taskListData = $taskList->toArray()['data'];
        foreach ($taskListData as &$task) {
            if (empty($task['start_time'])) {
                $task['start_time'] = '未开始';
            } else {
                $task['start_time'] = date('Y-m-d H:i:s', $task['start_time']);
            }
            if (empty($task['end_time'])) {
                $task['end_time'] = '未结束';
            } else {
                $task['end_time'] = date('Y-m-d H:i:s', $task['end_time']);
            }
        }

        $data = [
            'code' => 0,
            'msg' => '',
            'count' => $taskList->total(),
            'data' => $taskListData
        ];

        return json($data);
    }

    // 子任务添加页
    public function add()
    {
        $pid = (int)input('get.pid', '', 'strip_tags');

        // 当任务状态为已完成时，无法添加子任务
        $pTask = \app\frontend\model\Task::find($pid);
        if ($pTask->status == '已完成') {
            return view('error/error', [
                'msg' => '已完成的任务无法添加子任务'
            ]);
        }

        return view('', [
            'pid' => $pid
        ]);
    }

    // 富文本编辑器图片上传接口
    public function uploadImg()
    {
        $files = request()->file();
        $saveName = [];
        try {
            validate(['image' => ['fileSize:1024000', 'fileExt:jpg,png,gif,jpeg']])
                ->check($files);
            $ds = DIRECTORY_SEPARATOR;
            foreach($files as $file) {
                $saveName[] = $ds.'uploads'.$ds . Filesystem::disk('public')->putFile('image'.$ds.'temp', $file);
            }
        } catch (\think\exception\ValidateException $e) {
            return json([
                'errno' => 1,
                'data' => $e->getMessage()
            ]);
        }

        // 根据操作系统的不同对返回的saveName格式进行处理
        foreach ($saveName as &$v) {
            if ($ds == '/') {
                $v = str_replace('\\', $ds, $v);
            } else {
                $v = str_replace('/', $ds, $v);
            }
        }
        unset($v);

        return json([
            'errno' => 0,
            'data' => $saveName
        ]);
    }

    // 添加页面保存接口
    public function save()
    {
        $params['name'] = trim(input('post.name', '', 'strip_tags'));
        $params['pid'] = trim(input('post.pid', '', 'strip_tags'));
        $params['priority'] = trim(input('post.priority', '', 'strip_tags'));
        $params['type'] = trim(input('post.type', '', 'strip_tags'));
        $params['content'] = input('post.content', '');

        $validate = Validate::rule([
            'name|名称' => 'require|max:20',
            'content|详情描述' => 'max:65535',
            'priority|优先级' => 'require',
            'type|类型' => 'require'
        ]);
        if (!$validate->check($params)) {
            return json([
                'code' => 1,
                'msg' => $validate->getError()
            ]);
        }

        // 父任务处理
        $pTask = \app\frontend\model\Task::find($params['pid']);
        if ($pTask->status != '已拆分') {
            // 父任务的时间片处理
            $timeSlice = TimeSlice::where([
                'task_id' => $params['pid'],
                'end_time' => 0
            ])->find();
            if (!empty($timeSlice)) {
                $timeSlice->end_time = time();
                $timeSlice->save();
            }

            // 父任务状态修改为已拆分
            $pTask->status = 5;
            $pTask->save();
        }

        // 处理富文本编辑器传来的文本内容
        $newContent = $this->processContent($params['content']);

        // 启动事务
        Db::startTrans();
        try {
            $userInfo = session('userInfo');
            $taskModel = \app\frontend\model\Task::create([
                'name' => $params['name'],
                'project_id' => $pTask->project_id,
                'status' => 1,
                'user_id' => $userInfo['id'],
                'pid' => $params['pid'],
                'priority' => $params['priority'],
                'type' => $params['type']
            ]);

            // 插入task_content表
            TaskContent::create([
                'task_id' => $taskModel->id,
                'content' => htmlspecialchars($newContent)
            ]);

            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            return json([
                'code' => 2,
                'msg' => $e->getMessage()
            ]);
        }

        return json([
            'code' => 0,
            'msg' => '保存成功'
        ]);
    }

    // 任务查看编辑页
    public function edit()
    {
        // 任务信息
        $id = (int)input('get.id', '', 'strip_tags');
        $task = \app\frontend\model\Task::field('id,name,priority,type,symbol,addition_time')
            ->find($id);
        $task->taskContent();

        $taskData = [
            'id' => $id,
            'name' => $task['name'],
            'priority' => $task['priority'],
            'type' => $task['type'],
            'content' => $task['taskContent']['content'],
            'symbol' => $task['symbol'],
            'hour' => intval($task['addition_time'] / 3600),
            'minute' => ($task['addition_time'] % 3600) / 60
        ];

        return view('', [
            'task' => $taskData
        ]);
    }

    // 任务编辑页面保存接口
    public function update()
    {
        // 任务信息
        $params['id'] = (int)trim(input('post.id', '', 'strip_tags'));
        $params['name'] =  trim(input('post.name', '', 'strip_tags'));
        $params['priority'] = trim(input('post.priority', '', 'strip_tags'));
        $params['type'] = trim(input('post.type', '', 'strip_tags'));
        $params['content'] = input('post.content', '');
        $params['symbol'] =  trim(input('post.symbol', '', 'strip_tags'));
        $params['hour'] =  (int)trim(input('post.hour', '', 'strip_tags'));
        $params['minute'] =  (int)trim(input('post.minute', '', 'strip_tags'));

        // 格式验证
        $validate = Validate::rule([
            'id|id' => 'require|integer',
            'name|名称' => 'require|max:20',
            'priority|优先级' => 'require',
            'type|类型' => 'require'
        ]);
        if (!$validate->check($params)) {
            return json([
                'code' => 1,
                'msg' => $validate->getError()
            ]);
        }

        // 优先级参数设置
        switch ($params['priority']) {
            case '低':
                $params['priority'] = 1;
                break;
            case '中':
                $params['priority'] = 2;
                break;
            case '高':
                $params['priority'] = 3;
                break;
            default:
                return json([
                    'code' => 2,
                    'msg' => '优先级参数错误'
                ]);
        }


        // 类型参数设置
        switch ($params['type']) {
            case '需求任务':
                $params['type'] = 1;
                break;
            case '缺陷任务':
                $params['type'] = 2;
                break;
            default:
                return json([
                    'code' => 2,
                    'msg' => '类型参数错误'
                ]);
        }

        $taskModel = \app\frontend\model\Task::find($params['id']);

        // 富文本内容处理
        // 处理富文本编辑器传来的文本内容
        $newContent = $this->processContent($params['content']);
        // 找到原先content中存在但是富文本编辑器在本次编辑中删除的图片的url，然后删除该图片
        // 找到数据库中存储的content
        $oldContent = TaskContent::where('task_id', $params['id'])->find();
        $oldContent = htmlspecialchars_decode($oldContent['content']);
        // 正则表达式匹配查找图片路径
        $pattern = '/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.jpg|\.jpeg|\.png]))[\'|\"].*?[\/]?>/i';
        preg_match_all($pattern, $oldContent, $oldMatches);
        $oldImgs = $oldMatches[1];
        preg_match_all($pattern, $newContent, $newMatches);
        $newImgs = $newMatches[1];
        // 删除图片
        for ($i=0; $i < count($oldImgs); $i++) {
            if (!in_array($oldImgs[$i], $newImgs)) {
                unlink('.' . $oldImgs[$i]);
            }
        }

        // 将数据存入数据库
        Db::startTrans();
        try {
            // 更新requirement表
            $taskModel->name = $params['name'];
            $taskModel->priority = $params['priority'];
            $taskModel->type = $params['type'];
            $taskModel->symbol = $params['symbol'];
            $taskModel->addition_time = $params['hour'] * 3600 + $params['minute'] * 60;
            $taskModel->save();
            // 更新task_content表
            $taskContent = TaskContent::where('task_id', $params['id'])->find();
            $taskContent->content =htmlspecialchars($newContent);
            $taskContent->save();

            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            // 返回操作失败信息
            return json([
                'code' => 2,
                'msg' => '修改失败'
            ]);
        }

        return json([
            'code' => 0,
            'msg' => '修改成功'
        ]);
    }

    /**
     * 富文本编辑器文本内容处理
     * @param string $content 富文本编辑器文本内容
     * @return bool|mixed|null 处理的结果
     */
    private function processContent($content)
    {
        // 转移图片
        if (!empty($content)) {
            // 已经存在的图片
            $imgArray = [];
            // 完成处理的content
            $newContent = null;

            $ds = DIRECTORY_SEPARATOR;

            // 正则表达式匹配查找图片路径
            $pattern = '/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.jpg|\.jpeg|\.png]))[\'|\"].*?[\/]?>/i';
            preg_match_all($pattern, $content, $matches);
            $count = count($matches[1]);
            for ($i=0; $i < $count; $i++) {
                $editorImg = $matches[1][$i];
                // 根据操作系统的不同对返回的saveName格式进行处理
                if ($ds == '/') {
                    $editorImg = str_replace('\\', $ds, $editorImg);
                } else {
                    $editorImg = str_replace('/', $ds, $editorImg);
                }
                // 判断是否是新上传的图片
                $position = stripos($editorImg, $ds."temp".$ds);
                if ($position > 0) {    // 新上传的图片走这里
                    // 将图片从临时temp文件夹中迁移到article文件夹中
                    // 传过来的临时文件路径为：/uploads/image/temp/20201030/d885cc3b24b184a7c631408b5e0f670e.jpg
                    // 要迁移的文件路径：/uploads/image/article/20201030/d885cc3b24b184a7c631408b5e0f670e.jpg
                    // 新建日期文件夹
                    $tempArray = explode($ds, $editorImg);
                    $imageFloder = '.'.$ds.'uploads'.$ds.'image'.$ds.'task'.$ds . $tempArray[4];
                    if (!is_dir($imageFloder)) {
                        mkdir($imageFloder, 0777, true);
                    }
                    $tempImg = '.' . $editorImg;
                    $newImg = str_replace($ds.'temp'.$ds, $ds.'task'.$ds, $tempImg);
                    // 转移图片
                    rename($tempImg, $newImg);
                } else {
                    // 已经存在的图片走这里
                    $imgArray[] = $editorImg;
                }
            }

            // 重新整理content中的图片路径
            $newContent = str_replace($ds.'temp'.$ds, $ds.'task'.$ds, $content);
            return $newContent;
        }

        return false;
    }
}
